package com.jiuzhou.common.core.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JsonUtils {

        private static ObjectMapper objectMapper = new ObjectMapper();

        public static <T> String obj2String(T obj) {
            if(obj == null){
                return null;
            }
            String s = null;
            try {
                s = obj instanceof String ? (String)obj :  objectMapper.writeValueAsString(obj);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return s;
        }

        public static <T> String obj2StringPretty(T obj) {
            if (obj == null) {
                return null;
            }
            try {
                return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            } catch (JsonProcessingException e) {
                return null;
            }
        }

        public static <T> T string2Obj(String str, Class<T> clazz) {
            if(str == null || str.length()==0 || clazz == null){
                return null;
            }
            T t = null;
            try {
                t = clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return t;
        }

        /**
         * 在字符串与集合对象转换时使用
         */
        public static <T> T string2Obj(String str, TypeReference<T> typeReference) {
            if (str ==null || str.length() ==0 || typeReference == null) {
                return null;
            }
            try {
                return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
            } catch (IOException e) {
                return null;
            }
        }


    public static <T> byte[] obj2byte(T obj) {
        if(obj == null){
            return null;
        }
        byte[] bytes = null;
        try {
            bytes = objectMapper.writeValueAsBytes(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return bytes;
    }


        /**
         * 在字符串与集合对象转换时使用
         */
        public static <T> T string2Obj(String str, Class<?> collectionClazz, Class<?>... elementClazzes) {
            JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClazz, elementClazzes);
            try {
                return objectMapper.readValue(str, javaType);
            } catch (IOException e) {
                return null;
            }
        }

        //亮点：模拟构造方法设计模式提供类似于阿里巴巴FastJSON的put方式构造JSON功能
        public static JsonUtils.JsonBuilder builder() {
            return new JsonUtils.JsonBuilder();
        }

        public static class JsonBuilder {
            private Map<String ,Object> map = new HashMap<>();

            JsonBuilder() {
            }
            public JsonUtils.JsonBuilder put(String key ,Object value){
                map.put(key,value);
                return this;
            }

            public String build() {

                ObjectMapper objectMapper = new ObjectMapper();
                try {
                    return objectMapper.writeValueAsString(this.map);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                return "{}";
            }
        }


}
